package com.mocha.bass.test;

import cn.hutool.core.util.StrUtil;
import com.coffee.dict.DictDataDetail;
import com.coffee.dict.DictTargetType;
import com.coffee.dict.annotation.CoffeeDict;
import com.coffee.dict.annotation.CoffeeDictCollection;
import com.coffee.dict.annotation.CoffeeDictEntity;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

/**
 * @author songkui
 * @since 2024/5/8 16:12
 */
//@Slf4j
public class TransUtile {

    public static Object doTrans(Object result) {
        if (null == result) {
            return null;
        }

        //返回值中的泛型类型
        Object obj;
        //判断拦截的方法的返回值类型是否合法
        if (result instanceof List) {
            List olist = (List) result;
            if (olist.isEmpty()) {
                return result;
            }
            obj = olist.get(0);
        } else {
            obj = result;
        }

        //收集类中的字典翻译目录
        List<DictDataDetail> dictMapping = getDictMapping(obj.getClass());
        if (dictMapping.isEmpty()) {
            System.out.println("Not translatedict: List data not Map; list data: {}"+ obj.getClass());
            return result;
        }

        if (result instanceof List) {
            for (Object entity : (List) result) {
                assign(entity, dictMapping);
            }
        } else {
            assign(result, dictMapping);
        }

        return result;
    }


    /**
     * 翻译方法
     * <p>按照{@code dictMapping}中的目录参数信息，将{@code entity}中的字段翻译</p>
     *
     * @param entity      需要翻译的对象
     * @param dictMapping 具体字段翻译的配置
     */
    private static void assign(Object entity, List<DictDataDetail> dictMapping) {
        try {
            for (DictDataDetail dictDataDetail : dictMapping) {
                if (dictDataDetail.getDictTargetType() == DictTargetType.FIELD) {
                    String dictName = dictDataDetail.getSourceField();
                    String targetField = dictDataDetail.getTargetField();
                    if (StrUtil.isBlank(targetField)) {
                        targetField = dictName + "Name";
                    }
                    String nullValue = dictDataDetail.getNullValue();
                    String undefinedValue = dictDataDetail.getDefinedValue();
                    Map<String, String> dict = dictDataDetail.getDictDetail();

                    Class c = entity.getClass();
                    if (c != null) {
                        Field f = c.getDeclaredField(dictName);
                        f.setAccessible(true);
                        Field fvalue = c.getDeclaredField(targetField);
                        fvalue.setAccessible(true);
                        if (fvalue.getType() != String.class) {
                            System.out.println("dict Translation having an error. Field " + targetField + " typeis not String");
                            continue;
                        }
                        Object preValue = f.get(entity);
                        if (null != preValue) {
                            String preValueStr = String.valueOf(preValue);
                            // 需要赋值的字段
                            if (dictDataDetail.getMultiple()) {
                                StringBuffer buffer = new StringBuffer();
                                String[] strings = preValueStr.split(",");
                                for (String string : strings) {
                                    String name = dict.get(string);
                                    buffer.append(name == null ? undefinedValue : name).append(",");
                                }
                                fvalue.set(entity, buffer.deleteCharAt(buffer.length() - 1).toString());
                            } else {
                                String name = dict.get(preValueStr);
                                fvalue.set(entity, name == null ? undefinedValue : name);
                            }
                        } else {
                            fvalue.set(entity, nullValue);
                        }
                    }
                } else {
                     Field fvalue = entity.getClass().getDeclaredField(dictDataDetail.getSourceField());
                    fvalue.setAccessible(true);
                    Object preValue = fvalue.get(entity);
                    if (null != preValue) {
                        if (dictDataDetail.getDictTargetType() == DictTargetType.COLLECTION) {
                            for (Object o : (List) preValue) {
                                assign(o, dictDataDetail.getListDictInfo());
                            }
                        } else {
                            assign(preValue, dictDataDetail.getListDictInfo());
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("dict Translation having an error. " + e.toString());
        }
    }


    /**
     * 收集类中的字典翻译目录信息
     *
     * @param cla 要收集的类型
     * @return 定义的字典目录信息
     */
    private static List<DictDataDetail> getDictMapping(Class cla) {
        Field[] fields = cla.getDeclaredFields();
        List<DictDataDetail> list = new ArrayList<>();
        for (Field field : fields) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(CoffeeDict.class)) {
                CoffeeDict  coffeeDict = field.getAnnotation(CoffeeDict.class);
                list.add(new DictDataDetail(field.getName(), coffeeDict, getDictMapByName(coffeeDict.dictName())));
            } else if (field.isAnnotationPresent(CoffeeDictEntity.class)) {
                if (cla != field.getClass()) {
                    list.add(new DictDataDetail(DictTargetType.ENTITY, field.getName(), getDictMapping(field.getType())));
                } else {
                    System.out.println(field.getName() + "'s class type equals with parent is true");
                }
            } else if (field.isAnnotationPresent(CoffeeDictCollection.class)) {
                Type genericType = field.getGenericType();
                if (genericType == null) {
                    continue;
                }
                // 如果是泛型参数的类型
                if (genericType instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) genericType;
                    //得到泛型里的class类型对象
                    Class<?> genericClazz = (Class<?>) pt.getActualTypeArguments()[0];
                    if (genericClazz != cla) {
                        list.add(new DictDataDetail(DictTargetType.COLLECTION, field.getName(), getDictMapping(genericClazz)));
                    } else {
                        System.out.println(field.getName() + "'s class type equals with parent is true");
                    }
                } else if (genericType instanceof Collection) {
                    Collection c = (Collection) genericType; //TODO xxxxxx
                }
            }
        }
        return list;
    }

    public static Map<String, String> getDictMapByName(String dictName) {
        //举例，通过字典名称返回所有的字典项
        Map<String, String> map = new HashMap<>();
        switch (dictName) {
            case "sex":
                map.put("1", "男");
                map.put("2", "女");
                break;
            case "car:color":
                map.put("1", "芭比粉");
                map.put("2", "烈焰红");
                break;
            case "license:type":
                map.put("A1", "大型汽车");
                map.put("C1", "小型汽车");
                map.put("C2", "小型自动挡汽车");
                map.put("D", "普通三轮摩托车");
                break;
        }
        return map;
    }

}
